软件开发“教父”的20年,重构开发模式,重塑开发者思维
The following article is from 异步社区 Author 异步社区
脚本之家
你与百万开发者在一起
Martin Fowler,世界级软件开发大师,敏捷开发的开拓者和创始人全球知名的面向对象分析设计、UML、模式等专业领域的领头羊,首创敏捷开发方法论,被誉为软件开发“教父”,现任职于全球知名技术咨询公司ThoughtWorks,首席科学家。
Martin Fowler
坊间流传着这样一句话,如果有一本编程技术类书籍能够让读者在工作或实践多年后,还在反复咀嚼玩味、爱不释手、引导着读者前进着,那个必定是Martin Fowler的《重构》。
Martin还是IT领域的知名作家,他撰写的七本有关软件开发的书广受程序员们的喜爱,包括重构、企业应用程序体系结构模式和UML Distilled等领域。其中《重构》风靡国内外,拥有数百万读者,国内豆瓣评分高达9.5分。
Object Technology International, Inc,Erich Gamma 曾这样评价Martin:
Martin Fowler清楚地揭示了重构过程,他为面向对象软件开发所做的贡献难以估量。他解释了重构的原理和最佳实践,并指出何时何地你应该开始挖掘你的代码以求改善。
因此,我极力推荐你试试Martin Fowler的重构手法,你和你的程序都将因此更美好。
软件开发“教父”的重构生涯
Martin Fowler,1963年出生在英格兰的沃尔索耳,正是编程世界刚刚起步的年代。
Martin 在80年代初开始接触软件行业,那时候Smalltalk还是一门很火的语言,大家都在学习这门语言,而Martin也刚开始从事软件工作——关于信息系统对象建模方面的顾问。
那个年代没有任何有关面向对象分析和设计的书籍,大家都是用一种简单的图符表示法,然后提出一个简单的建模过程,最后用几个简单的示例来加以说明。但Martin认为不应该把重点放在过程——即如何建模,而是把重点放在过程的结果——即模型本身,尽管这与当时大环境下的创建方式是相悖的。
到了90年代初,Martin发现,大多数程序员很难通过紧跟技术创新的脚步来享受软件工程领域的新成果。
身为一个信息系统对象建模顾问, Martin从Smalltalk上学得的专业知识是远远超过这个职业所需要的,他觉得自己既然有了这些建模方面的理念,同时又对编程方面很感兴趣,所以他不单在建模方面帮助别人,还在编程方面进行指导——借助外力的帮助,精确地运用UML。
从建模到编程语言,他把这些都看成一件完整的、而非毫无关联的事。
这样的工作持续了近十年,1999年,Martin迎来了他人生中意义重大的一年。
那时Martin造访了客户调研的开发项目时发现,该系统的核心继承体系相当凌乱,为此,他建议负责该项目的经理将这些代码进行整理,但是项目经理认为在项目面临很大的进度压力下,只要程序看上去还可以运行就算是完成。
这种情况下,《重构:改善既有代码的设计》面世了,Martin在这本书中揭示了重构的过程,解释了重构的原理和最佳实践方式,并给出了何时以及何地应该开始挖掘代码以求改善。
重构这个理念一经推出,受到了广大程序员的喜爱,他们觉得在不改变代码外在行为的前提下,对代码做出修改,以改进程序的内部结构是一个非常妙的事。后来,这本风靡国际IT行业的《重构》被引入国内,在豆瓣评分以9.2的高分长期霸屏程序员必读书单中。
2010年,第五届敏捷软件开发大会“敏捷中国2010”上,Martin的“敏捷宣言”又一次引领了整个IT行业对敏捷开发的认识,从此“敏捷”二字开始风行国内 IT 领域。对程序员们来说,他就是当之无愧的先行者。
Martin Fowler
就在去年,这位先行者又全面升级了《重构》,《重构:改善既有代码的设计(第2版)》面世了,国内外掀起一阵抢购热潮,豆瓣评分更是高达9.5分。
Martin定义的重构到底是什么?
说起重构,还要从1999年发生在Martin身上的一件事说起。面对凌乱的系统的核心继承体系,他建议负责该项目的经理将这些代码进行整理,但是被项目经理拒绝。
随后,Martin把自己的想法第一时间告诉了在这个继承体系上工作的程序员,程序员都很敏锐, 马上就看出问题的严重性,特别是在这种需要借助外力才能发现问题。他们立刻用了两天的时间整理好这个继承体系,并删掉了其中一半代码,功能毫发无损,而且发现在继承体系中加入新的类或使用系统中的其他类都更快、更容易了,他们十分感谢Martin。
但项目经理很不高兴,他觉得这些程序员却白白耗费了两天时间,做的工作却与未来几个月要交付的大量功能毫不相干,明明原先的代码运行起来还算正常,为什么要为了可能发生的问题去花费时间提前预防呢?
不过在6个月之后,这个项目还是宣告失败了,原因是代码太复杂,无法调试,也无法将性能调优到可接受的水平。再后来,这个项目重新启动,唯一的解决办法就是从头开始编写整个系统,Kent Beck 受邀做了顾问。他做了几件迥异以往的事,其中最重要的一件就是听从Martin的建议,坚持以持续不断的重构行为来整理代码。
那时,Martin第一次认识到重构的重要且不可替代性。
“重构”这个概念最开始来自于 Smalltalk圈子,由于重构是框架开发中不可缺少的一部分,所以当框架设计者讨论自己的工作时,这个术语就诞生了。
当他们精炼自己的类继承体系时,当他们叫喊自己可以拿掉多少多少行代码时,重构的概念慢慢浮出水面,后来重构就进入了其他编程语言阵营之中。
说得直白一点,所谓重构(refactoring)就是这样一个过程:在不改变代码外在行为的前提下,对代码做出修改,以改进程序的内部结构。
重构是一种经千锤百炼形成的有条不紊的程序整理方法,可以最大限度地减小整理过程中引入错误的概率。本质上说,重构就是在代码写好之后改进它的设计。
“在代码写好之后改进它的设计”这种说法有点儿奇怪。在软件开发的大部分历史时期,大部分人认为,应该先设计而后编码:首先得有一个良好的设计,然后才能开始编码。
但是,随着时间流逝,人们不断修改代码,于是根据原先设计所得的系统,整体结构逐渐衰弱。代码质量慢慢沉沦,编码工作从严谨的工程堕落为胡砍乱劈的随性行为。
而“重构”正好与此相反。
哪怕手上有一个糟糕的设计,甚至是一堆混乱的代码,我们也可以借由重构将它加工成设计良好的代码。重构的每个步骤都很简单,甚至显得有些过于简单:只需要把某个字段从一个类移到另一个类,把某些代码从一个函数拉出来构成另一个函数,或是在继承体系中把某些代码推上推下就行了。
但是,聚沙成塔,这些小小的修改累积起来就可以根本改善设计质量。这和一般常见的“软件会慢慢腐烂”的观点恰恰相反。
有了重构以后,Martin发现工作的平衡点开始发生变化,例如,设计不是在一开始完成的,而是在整个开发过程中逐渐浮现出来。在系统构筑过程中,他学会了如何不断改进设计。这个“构筑-设计”的反复互动,可以让一个程序在开发过程中持续保有良好的设计。
Martin认为,重构这东西不可能一开始就完全正确,它将随着设计者的经验成长而进化,代码被阅读和被修改的次数远远多于它被编写的次数。而保持代码易读、易修改的关键,就是重构。
作为一本为专业程序员编写的重构指南——《重构》,Martin的目的是告诉所有程序员如何以一种可控且高效的方式进行重构,从而减少了开发过程中的风险。
书里提出的重构准则将帮助他们学习如何有条不紊地、一次一小步地修改代码、改进程序结构,且不会引入错误的正确的重构方式,最终得到有效的、长期可运行的代码程序,而不是去遵循那句古老的工程谚语:“如果它还可以运行,就不要动它。”
重构再度升级
《重构》自1999年面世以来,已经经过21年了。软件行业里新的编程语言不断涌现,老的编程语言也加快迭代,而函数式编程和面向对象一样成了主流编程语言的标配。不仅软件开发技术发生了很多重要的变化,各种软件开发工具也日益现代化,对开发的更好支持也已成为主流编程语言新的核心竞争力。
而现在, “重构”这一理念已被读者广泛接纳,作为一种经千锤百炼形成的有条不紊的程序整理方法,能够最大限度地减小整理过程中引入错误的概率,成为编程的词汇表中不可或缺的部分,《重构》一书至今依旧被无数程序员奉为软件开发领域的经典之作。
但重构的扎实功夫要学起来、做起来,颇不是件轻松的事,且不说详尽到近乎琐碎的重构手法,光是单元测试一事,怕是已有九成程序员无法企及,渐渐地,“重构”成了一块漂亮的招牌,大家都愿意挂上这个名号,可实际上干的却多是“刀劈斧砍”的勾当。
就国内先如今的情况而论,“重构”概念的表里分离,大有愈演愈烈之势。随着当年的一线技术人员纷纷走上领导岗位,他们乐于将“重构”这块漂亮招牌用在更宽泛的环境下,例如系统架构乃至组织结构,都可以“重构”一下。
然而基本功的欠缺,却也一路如影随形。当年在对象中的刀劈斧砍,如今被照搬到了架构、组织的调整。于是“重构”的痛苦回忆又一遍遍重演,甚而程度更深、影响更广、危害更烈。
通过重构,现在的程序员普遍通过微增量来开发系统、编写测试用例。但Martin认为这远远不够,重构的影响其实应该更广泛,20年前,他和其他先行者鼓励大家都接受重构这一概念,但是,在整个行业普及重构仍需要相当长的时间。
对于IT领域来说,Martin不仅仅是一个先行者,他还是一个引路者。
Martin希望看到更多人使用他们大力推广的测试法,使用持续集成和持续交付等方法。但涉及上述概念,Martin觉得自己只能尽量在书中,从主客观上尽可能详尽地解释这些技术,并希望这会说服更多人进行尝试,“当他们尝到甜头后就会在工作中真正用上这些方法“。
针对这一现象,Martin推出了《重构:改善既有代码的设计(第2版)》,他在第1版的基础上做了全面修订,反映了编程领域业20年来发生的许多变化,但Martin传递的理念也始终如一:不改变外在行为,而提高代码质量,但将基础功夫做得更扎实。让人不禁感叹于他对“微末功夫”的执着!
很多人好奇Martin为什么决定将《重构》再版?Martin给出了3个原因:
第1版里的代码已经很陈旧了,书里面还有Java.util.Vector;
一些重构并非是与面向对象紧耦合在一起的;
Martin认为Java是一种非常严格的面向对象编程语言,而第1版中所有的重构都是基于面向对象的,他想通过再版来说明每个程序员都可以用任何(编程)语言、在任何环境中、遵循书中提到的范例进行重构,这也是他决定再版《重构》的源动力。
Martin认为重构的基本机制不会发生巨大转变,即使使用面向对象语言工作也是如此。他觉得有一等函数很好,可以尝试许多函数式的理念,例如,写软件时大部分函数都具备引用透明性,这在面向对象系统和在函数式系统中都是好事。
所以Martin不像许多人那样在函数式编程和面向对象编程间画出明确界限,他认为两者有很多共同的地方,未必存在巨大差异。他鼓励程序员不要有门户之见,要用综合理念来解决问题。
对于最新版《重构》,Martin认为有一个重构手法也许值得注意,拆分阶段(split phase)。早在几年前,当Martin和Ken Beck商谈拆分阶段的时候,Martin第一次意识到这也是重构手法。
通过这种重构手法,Martin将大量计算合理分为两个阶段,使用中间数据结构进行通信。其中一个例子是解析拆分阶段可有效地将token从解析中抽离出来,这样就得到了一个可可保存在存储器种的token流,可处理相关字符串、文本字符串。
Martin Fowler
而说到重构工具,Martin和Kent做了很多年了,但他们从来没有意识到工具的重要性;当他们意识到这一点之后,他们感觉重构工具已经无处不在,他们认为这个内容非常重要,然后Martin就真把这些新内容加到新版中了。
重构的关键是理念:通过进行最细微的改变,然后将这些变化串联起来,这就是重构思维核心。将一个大变化拆分为许多小变化,又在尽可能多进行细微变化的同时,不改变系统的整体表现,然后随时间推移,反复练习并思考如何进行拆分。Martin在《重构 2》一书中说过,他通过重构框架思考问题的体验,尝试各种高效的重构手法并做出决定,最重要的就是通过实践进行重构。
他认为在尝试了不同的重构手法后,找出能重构手法生成理想序列,继而进行尝试识别出这种重构手法,而同样的逻辑也适用于更广泛的层面。
因此,他采用了70多个种可行的重构,并且把每个重构都介绍了一种经过验证的代码变换手法的动机和技术。就像软件开发的大多数工作一样,重构除了动手做,别无他法,必须反复实践,必须在项目中使用重构。
Martin始终希望,重构准则能帮助大家一步步修改自己的代码,减少了开发过程中的风险。
重构=编码
在日新月异的 IT 技术世界里,不变的东西其实还是有的——重构。
从《重构》的英文原版引进国内,到现在已经过去20年了。Martin Fowler 这次对本书进行的重构,体现了近年来编程领域的一些思潮变化,既有设计,又永远有改进空间。
尽管时间是最强大的重构工具,连书里的示例语言都从 Java 变成 JavaScript 了,但书中的理念和实践的价值并没有随时间流逝。
重构早就成了软件开发从业者本能的一部分,每个 IDE 都内置了重构功能,每个程序员都定期重构自己的代码。
对于软件工程师来说,重构,并不是额外的工作,它就是编码本身。切实地读懂了《重构》的软件工程师,在能力上都会获得一个数量级的提升。
参考文献:
《分析模式:可重用对象模型》 作者:Martin Fowler
《UML精粹:一个简短的指南标准对象建模语言》 作者:Martin Fowler
《重构:改善既有代码的设计》 作者:Martin Fowler
软件开发教父,Martin Fowler:https://zhuanlan.zhihu.com/p/71216874
福
利
来
了
小编为我们喜爱阅读的书迷们免费送书。
玩法再升级!!!
留言点赞送书活动规则
留言点赞:留言分享你是什么时间接触到重构理念,或者其他一些学习经历。
特别申明:
1、一位用户1个月内只能有1次获奖机会,让更多粉丝受益活动才更有意义
2、每一位用户只有1次留言机会,不允许重复留言~
请大家记住这三个1哦
活动截止时间:2020 年 04 月 07 日 16:00 整。
玩法3,赶快来参与吧
👇🏻👇🏻👇🏻点击卡片进入小程序,坚持打卡
签到累计积分 兑换书籍好物
精选书单 点蓝字即可
更多好书请关注脚本之家官方书店